package com.ponhu.ea2.goodsCenter.provider.biz.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.CaseFormat;
import com.google.common.collect.Maps;
import com.ponhu.ea2.common.basic.model.PagedResult;
import com.ponhu.ea2.common.basic.util.time.DateUtils;
import com.ponhu.ea2.constants.CommonConstant;
import com.ponhu.ea2.goodsCenter.provider.biz.ESPickInventoryService;
import com.ponhu.ea2.goodsCenter.provider.utils.LocalDateUtil;
import com.ponhu.ea2.goodsCenter.provider.utils.ProBeanUtils;
import com.ponhu.ea2.properties.GoodsProperties;
import com.ponhu.ea2.goodsCenter.provider.mapper.InventoryMapper;
import com.ponhu.ea2.query.PickInventoryQuery;
import com.ponhu.ea2.scmcenter.facade.bms.common.CommonService;
import com.ponhu.ea2.scmcenter.model.vo.common.CommonTypeVo;
import com.ponhu.ea2.stockcenter.service.bms.StockCommonService;
import com.ponhu.ea2.stockcenter.vo.WarehouseInfoVo;
import com.ponhu.ea2.support.exception.BusinessRuntimeException;
import com.ponhu.ea2.vo.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.*;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.metrics.sum.ParsedSum;
import org.elasticsearch.search.aggregations.metrics.sum.SumAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.Period;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;

import static com.ponhu.ea2.common.basic.util.time.DateUtils.DATE_FORMAT_YYYY_MM_DD_HH_MM_SS;
import static com.ponhu.ea2.enums.ResponseCodeEnum.PICK_INVENTORY_DEEP_PAGED_LIMIT;

/**
 * @author Wang
 * @date 2022/3/24 3:13 下午
 */
@Service
public class ESPickInventoryServiceImpl implements ESPickInventoryService {

    @DubboReference(version = "1.0.0", check = false)
    private StockCommonService stockCommonService;
    @DubboReference(version = "1.0.0", check = false)
    private CommonService commonService;

    @Resource
    private RestHighLevelClient restHighLevelClient;
    @Autowired
    private InventoryMapper inventoryMapper;
    @Resource
    private GoodsProperties goodsProperties;

    @Override
    public PagedResult<PickInventoryVo> getPickInventoryListFromES(PickInventoryQuery query) throws IOException {
        int offset = convertAndSetPageParams(query);
        //校验是否超过深分页限制
        checkDeepPaged(query, offset);

        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices(goodsProperties.getES_INDEX_PICK_INVENTORY());
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        BoolQueryBuilder boolQueryBuilder = getQueryBuilder(query);
        searchSourceBuilder.query(boolQueryBuilder);
        //设置排序条件
        if (query.getOrderModel() != null) {
            String esFieldName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, query.getOrderModel().getOrderColumn());
            searchSourceBuilder.sort(esFieldName,
                    "desc".equals(query.getOrderModel().getOrderRegular()) ? SortOrder.DESC : SortOrder.ASC);
        } else {
            searchSourceBuilder.sort("createTime", SortOrder.DESC);
        }

        //offset,从0开始
        searchSourceBuilder.from(offset);
        searchSourceBuilder.size(query.getPageSize());

        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest);

        SearchHits hits = search.getHits();
        long totalHits = hits.getTotalHits();
        SearchHit[] searchHits = hits.getHits();

        //组装分页对象
        PagedResult<PickInventoryVo> pagedResult = new PagedResult<>();
        pagedResult.setPageIndex(query.getPageIndex());
        pagedResult.setPageSize(query.getPageSize());
        pagedResult.setTotal(totalHits);

        if (searchHits == null || searchHits.length == 0) {
            pagedResult.setResult(null);
            pagedResult.setPageCount(0);
            return pagedResult;
        }

        List<ESPickInventoryVo> collect = Arrays.stream(searchHits).map(i -> {
                            return JSONObject.parseObject(i.getSourceAsString(), ESPickInventoryVo.class);
                        }
                )
                .collect(Collectors.toList());
        //转换ES数据到选品前端数据模型
        List<PickInventoryVo> data = convertPickInventoryList(collect);

        pagedResult.setPageCount(getPageCount(totalHits, query.getPageSize()));
        pagedResult.setResult(data);
        return pagedResult;
    }

    private void checkDeepPaged(PickInventoryQuery query, int offset) {
        if ((offset + query.getPageSize()) > 10000) {
            int maxPageNum = (10000 - query.getPageSize()) / query.getPageSize() + 1;
            String msg = String.format("已超出最大页码%s页，试试更多筛选条件吧", maxPageNum);
            throw new BusinessRuntimeException(PICK_INVENTORY_DEEP_PAGED_LIMIT.getCode(), msg);
        }
    }

    private int getPageCount(long totalHits, int pageSize) {
        if (totalHits == 0) {
            return 0;
        } else {
            return (int) totalHits / pageSize + 1;
        }
    }

    private List<PickInventoryVo> convertPickInventoryList(List<ESPickInventoryVo> collect) {
        if (CollectionUtils.isEmpty(collect)) {
            return null;
        }
        //获取所有仓库数据
        List<WarehouseInfoVo> warehouseInfoVos = stockCommonService.getAllWarehouseInfos();
        Map<String, String> warehouseMap = warehouseInfoVos.stream().collect(Collectors.toMap(WarehouseInfoVo::getWhCode, WarehouseInfoVo::getWhName));

        List<PickInventoryVo> pickInventoryVos = collect.stream().map(esVo -> {
            PickInventoryVo pickInventoryVo = new PickInventoryVo();
            BeanUtils.copyProperties(esVo, pickInventoryVo);
            pickInventoryVo.setCategoryName(
                    String.format("%s-%s-%s", esVo.getFirstCategoryName(), esVo.getSecondCategoryName(), esVo.getCategoryName()));

            //仓库位置
            if (CollectionUtils.isNotEmpty(esVo.getWarehouseData())) {
                List<String> warehouseList = esVo.getWarehouseData().stream().map(i -> {
                    return StringUtils.defaultString(warehouseMap.get(i.getWarehouseCode()), i.getWarehouseCode()) + "：" + i.getRealStockNum();
                }).collect(Collectors.toList());
                pickInventoryVo.setWarehousePlace(String.join(",", warehouseList));
            }
            //创建时间
            pickInventoryVo.setCreateTime(LocalDateUtil.dateToLocalDateTime(esVo.getCreateTime()));
            //属性数据
            List<PhPropertyVo> allPropList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(esVo.getInventoryPropData())) {
                List<PhPropertyVo> propertyVoList = esVo.getInventoryPropData().stream().map(i -> {
                    PhPropertyVo propertyVo = new PhPropertyVo();
                    propertyVo.setPropertyName(i.getName());
                    propertyVo.setPropertyValue(i.getValue());
                    propertyVo.setPropertyId(i.getValueId());
                    return propertyVo;
                }).collect(Collectors.toList());
                allPropList.addAll(propertyVoList);
            }
            //物料数据
            if (CollectionUtils.isNotEmpty(esVo.getMaterialPropData())) {
                List<PhPropertyVo> propertyVoList = esVo.getMaterialPropData().stream().map(i -> {
                    PhPropertyVo propertyVo = new PhPropertyVo();
                    propertyVo.setPropertyName(i.getName());
                    propertyVo.setPropertyValue(i.getValue());
                    propertyVo.setPropertyId(i.getValueId());
                    return propertyVo;
                }).collect(Collectors.toList());
                allPropList.addAll(propertyVoList);
            }
            pickInventoryVo.setPropertyVoList(allPropList);

            return pickInventoryVo;
        }).collect(Collectors.toList());

        return pickInventoryVos;
    }

    private int convertAndSetPageParams(PickInventoryQuery query) {
        if (query.getPageIndex() < 1) {
            query.setPageIndex(1);
        }
        if (query.getPageSize() < 1) {
            query.setPageIndex(10);
        }

        int offset = (query.getPageIndex() - 1) * query.getPageSize();
        return offset;
    }

    @Override
    public PickInventoryStatisticsVo getPickInventoryStatisticsInfoFromES(PickInventoryQuery query) {
        try {
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices(goodsProperties.getES_INDEX_PICK_INVENTORY());
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.query(getQueryBuilder(query));

            SumAggregationBuilder totalRealStockNum = AggregationBuilders.sum("totalRealStockNum").field("totalRealStockNum");
            SumAggregationBuilder priceSum = AggregationBuilders.sum("priceSum").script(new Script("doc.totalRealStockNum.value * doc.warehousePrice.value"));
            searchSourceBuilder.aggregation(totalRealStockNum);
            searchSourceBuilder.aggregation(priceSum);
            searchRequest.source(searchSourceBuilder);
            SearchResponse search = restHighLevelClient.search(searchRequest);
            SearchHits hits = search.getHits();

            Aggregations aggregations = search.getAggregations();
            ParsedSum parsedSumPriceSum = aggregations.get("priceSum");
            ParsedSum parsedSumStockNum = aggregations.get("totalRealStockNum");

            return new PickInventoryStatisticsVo()
                    .setTotalAmount(new BigDecimal(parsedSumPriceSum.getValue()))
                    .setInventoryCount(Integer.parseInt(String.valueOf(hits.getTotalHits())))
                    .setTotalStockNum(((Double) parsedSumStockNum.getValue()).longValue());
        } catch (IOException e) {
            e.printStackTrace();
            return new PickInventoryStatisticsVo();
        }
    }

    @Override
    public List<PickInventoryDetailVo> exportPickInventoryDataList(PickInventoryQuery pickInventoryQuery) {
        try {
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices(goodsProperties.getES_INDEX_PICK_INVENTORY());
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

            searchSourceBuilder.query(getQueryBuilder(pickInventoryQuery));
            searchSourceBuilder.from(0).size(3000);

            //设置排序条件
            if (pickInventoryQuery.getOrderModel() != null) {
                String esFieldName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL,
                        pickInventoryQuery.getOrderModel().getOrderColumn());
                searchSourceBuilder.sort(esFieldName,
                        "desc".equals(pickInventoryQuery.getOrderModel().getOrderRegular()) ? SortOrder.DESC : SortOrder.ASC);
            } else {
                searchSourceBuilder.sort("createTime", SortOrder.DESC);
            }

            searchRequest.source(searchSourceBuilder);
//            System.out.printf("\033[32m %s \033[0m\n", searchRequest);

            SearchResponse searchResponse = restHighLevelClient.search(searchRequest);

            SearchHits responseHits = searchResponse.getHits();
            long totalHits = responseHits.getTotalHits();
            if (totalHits == 0) return Lists.newArrayList();

            Map<Long, String> channelMap = Maps.newHashMap();
            List<Long> channelIds = Arrays.stream(responseHits.getHits()).flatMap(hit -> {
                ESPickInventoryVo esPickInventoryVo = JSONObject.parseObject(hit.getSourceAsString(), ESPickInventoryVo.class);
                List<ESPickInventoryPurchaseVo> purchaseData = esPickInventoryVo.getPurchaseData();
                if (CollectionUtils.isEmpty(purchaseData)) {
                    List<Long> emptyList = Lists.newArrayList();
                    return emptyList.stream();
                }
                return purchaseData.stream().map(ESPickInventoryPurchaseVo::getPurchaseChannelId);
            }).distinct().collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(channelIds)) {
                channelMap = inventoryMapper.getPurchaseChannelsByIds(channelIds).stream().collect(Collectors
                        .toMap(PurchaseChannelVo::getChannelId, PurchaseChannelVo::getChannelName, (v1, v2) -> v2));
            }

            //获取所有仓库数据
            Map<String, String> warehouseMap = stockCommonService.getAllWarehouseInfos().stream()
                    .collect(Collectors.toMap(WarehouseInfoVo::getWhCode, WarehouseInfoVo::getWhName));
//            Map<String, String> warehouseMap = Maps.newHashMap();

            //获取所有入库方式数据
            Map<Integer, String> whTypeMap = commonService.wareHouseTypeList().stream()
                    .collect(Collectors.toMap(CommonTypeVo::getId, CommonTypeVo::getValue, (v1, v2) -> v2));
//            Map<String, String> whTypeMap = Maps.newHashMap();

            Map<Long, String> finalChannelMap = channelMap;
            return Arrays.stream(responseHits.getHits()).map(hit -> {
                ESPickInventoryVo esPickInventoryVo = JSONObject.parseObject(hit.getSourceAsString(), ESPickInventoryVo.class);
                PickInventoryDetailVo pickInventoryDetailVo = ProBeanUtils.copyProperties(esPickInventoryVo, PickInventoryDetailVo.class);

                PhMaterialVo phMaterialVo = ProBeanUtils.copyProperties(esPickInventoryVo, PhMaterialVo.class)
                        .setUnit(esPickInventoryVo.getMaterialUnit())
                        .setThirdCategoryName(esPickInventoryVo.getCategoryName());

                if (ObjectUtils.isNotEmpty(esPickInventoryVo.getMaterialPropData())) {
                    List<PhPropertyVo> materialProps = esPickInventoryVo.getMaterialPropData().stream()
                            .filter(prop -> StringUtils.isNotEmpty(prop.getName()))
                            .map(esVo -> new PhPropertyVo().setPropertyId(esVo.getValueId())
                                    .setPropertyName(esVo.getName()).setPropertyValue(esVo.getValue()))
                            .collect(Collectors.toList());
                    phMaterialVo.setMaterialPropertyValueList(materialProps);
                }
                pickInventoryDetailVo.setPhMaterialVo(phMaterialVo);

                if (ObjectUtils.isNotEmpty(esPickInventoryVo.getInventoryPropData())) {
                    List<PhPropertyVo> phPropertList = esPickInventoryVo.getInventoryPropData().stream()
                            .filter(prop -> StringUtils.isNotEmpty(prop.getName()))
                            .map(esVo -> new PhPropertyVo().setPropertyId(esVo.getValueId())
                                    .setPropertyName(esVo.getName()).setPropertyValue(esVo.getValue()))
                            .collect(Collectors.toList());
                    pickInventoryDetailVo.setPhPropertList(phPropertList);
                }

                // 处理采购信息
                List<ESPickInventoryPurchaseVo> purchaseData = esPickInventoryVo.getPurchaseData();
                if (CollectionUtils.isNotEmpty(purchaseData) && esPickInventoryVo.getIsSecondhand() == CommonConstant.YES_OR_NO.YES) {
                    String warehouseTypeName = purchaseData.stream().map(ESPickInventoryPurchaseVo::getWarehouseWay)
                            .distinct().map(typeId -> whTypeMap.get(typeId.intValue())).filter(StringUtils::isNotEmpty).collect(Collectors.joining(","));
                    String procurementTypes = purchaseData.stream().map(ESPickInventoryPurchaseVo::getPurchaseTypeId)
                            .distinct().map(String::valueOf).collect(Collectors.joining(","));
                    String suppName = purchaseData.stream().map(ESPickInventoryPurchaseVo::getVendorName)
                            .distinct().collect(Collectors.joining(","));
                    String channelName = purchaseData.stream().map(ESPickInventoryPurchaseVo::getPurchaseChannelId)
                            .map(channelId -> finalChannelMap.get(channelId)).filter(StringUtils::isNotEmpty).collect(Collectors.joining(","));
                    PickInventoryPurchaseVo pickInventoryPurchaseVo = new PickInventoryPurchaseVo()
                            .setInventoryCode(esPickInventoryVo.getInventoryCode())
                            .setWarehouseTypeName(warehouseTypeName)
                            .setProcurementTypes(procurementTypes)
                            .setChannelName(channelName)
                            .setSuppName(suppName);
                    pickInventoryDetailVo.setPickInventoryPurchaseVo(pickInventoryPurchaseVo);
                }

                // 处理货品附件/配件
                if (CollectionUtils.isNotEmpty(esPickInventoryVo.getAccessoryList())) {
                    List<PhInventoryAccessoryVo> accessoryList = esPickInventoryVo.getAccessoryList().stream()
                            .map(aName -> new PhInventoryAccessoryVo().setDictItemLabel(aName)).collect(Collectors.toList());
                    pickInventoryDetailVo.setAccessoryList(accessoryList);
                }
                if (CollectionUtils.isNotEmpty(esPickInventoryVo.getAnnexList())) {
                    List<PhInventoryAccessoryVo> annexList = esPickInventoryVo.getAnnexList().stream()
                            .map(aName -> new PhInventoryAccessoryVo().setDictItemLabel(aName)).collect(Collectors.toList());
                    pickInventoryDetailVo.setAnnexList(annexList);
                }

                //仓库位置
                if (CollectionUtils.isNotEmpty(esPickInventoryVo.getWarehouseData())) {
                    List<String> warehouseList = esPickInventoryVo.getWarehouseData().stream().map(i ->
                                    StringUtils.defaultString(warehouseMap.get(i.getWarehouseCode()), i.getWarehouseCode()) + "：" + i.getRealStockNum())
                            .collect(Collectors.toList());
                    pickInventoryDetailVo.setWarehousePlace(String.join(",", warehouseList));
                }
                // 在库时长
                Date warehouseAliveStart = esPickInventoryVo.getWarehouseAliveStart();
                if (ObjectUtils.isNotEmpty(warehouseAliveStart)) {
                    Date warehouseAliveEnd = ObjectUtils.defaultIfNull(esPickInventoryVo.getWarehouseAliveEnd(), Date.from(Instant.now()));
                    int dayOfTwoDatetime = Period.between(LocalDateUtil.dateToLocalDate(warehouseAliveStart),
                            LocalDateUtil.dateToLocalDate(warehouseAliveEnd)).getDays();
                    pickInventoryDetailVo.setWarehouseAliveDay(dayOfTwoDatetime);
                }

                return pickInventoryDetailVo;
            }).collect(Collectors.toList());
        } catch (IOException e) {
            e.printStackTrace();
            return Lists.newArrayList();
        }
    }

    private BoolQueryBuilder getQueryBuilder(PickInventoryQuery query) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        if (query.getInventoryId() != null) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("inventoryId", query.getInventoryId()));
        }
        if (!"yes".equals(query.getPickInventoryRule())) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("isKpi", 2));
        }
        if (CollectionUtils.isNotEmpty(query.getQuantityIdList())) {
            boolQueryBuilder.filter(QueryBuilders.termsQuery("qualityId", query.getQuantityIdList()));
        }
        if (StringUtils.isNotEmpty(query.getMaterialCode())) {
            boolQueryBuilder.filter(QueryBuilders.wildcardQuery("materialCode", "*" + query.getMaterialCode() + "*"));
        }
        if (CollectionUtils.isNotEmpty(query.getBrandIdList())) {
            boolQueryBuilder.filter(QueryBuilders.termsQuery("brandId", query.getBrandIdList()));
        }
        if (query.getCategoryId() != null && query.getCategoryId() > 0) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("categoryId", query.getCategoryId()));
        }
        if (CollectionUtils.isNotEmpty(query.getCategoryIds())) {
            boolQueryBuilder.filter(QueryBuilders.termsQuery("categoryId", query.getCategoryIds()));
        }
        if (query.getSeriesId() != null && query.getSeriesId() > 0) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("seriesId", query.getSeriesId()));
        }
        if (query.getModelId() != null && query.getModelId() > 0) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("modelId", query.getModelId()));
        }
        if (StringUtils.isNotEmpty(query.getSeriesName())) {
            boolQueryBuilder.filter(QueryBuilders.wildcardQuery("seriesName", "*" + query.getSeriesName() + "*"));
        }
        if (StringUtils.isNotEmpty(query.getModelName())) {
            boolQueryBuilder.filter(QueryBuilders.wildcardQuery("modelName", "*" + query.getModelName() + "*"));
        }
        if (CollectionUtils.isNotEmpty(query.getInventoryCodeList())) {
            boolQueryBuilder.filter(QueryBuilders.termsQuery("inventoryCode", query.getInventoryCodeList()));
        }
        if (StringUtils.isNotEmpty(query.getInventoryCode())) {
            boolQueryBuilder.filter(QueryBuilders.wildcardQuery("inventoryCode", "*" + query.getInventoryCode() + "*"));
        }
        if (StringUtils.isNotEmpty(query.getInventoryName())) {
            boolQueryBuilder.filter(QueryBuilders.wildcardQuery("inventoryName", "*" + query.getInventoryName() + "*"));
        }
        if (StringUtils.isNotEmpty(query.getCreateTimeStart()) && StringUtils.isEmpty(query.getCreateTimeEnd())) {
            long time = DateUtils.str2Date(query.getCreateTimeStart(), DATE_FORMAT_YYYY_MM_DD_HH_MM_SS).getTime();
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("createTime").gte(time));
        }
        if (StringUtils.isEmpty(query.getCreateTimeStart()) && StringUtils.isNotEmpty(query.getCreateTimeEnd())) {
            long time = DateUtils.str2Date(query.getCreateTimeEnd(), DATE_FORMAT_YYYY_MM_DD_HH_MM_SS).getTime();
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("createTime").lte(time));
        }
        if (StringUtils.isNotEmpty(query.getCreateTimeStart()) && StringUtils.isNotEmpty(query.getCreateTimeEnd())) {
            long sTime = DateUtils.str2Date(query.getCreateTimeStart(), DATE_FORMAT_YYYY_MM_DD_HH_MM_SS).getTime();
            long eTime = DateUtils.str2Date(query.getCreateTimeEnd(), DATE_FORMAT_YYYY_MM_DD_HH_MM_SS).getTime();
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("createTime").from(sTime).to(eTime));
        }
        if (query.getIsSecondhand() != null && query.getIsSecondhand() > 0) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("isSecondhand", query.getIsSecondhand()));
        }
        if (query.getCcicStatus() != null && query.getCcicStatus() > 0) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("ccicStatus", query.getCcicStatus()));
        }
        if (CollectionUtils.isNotEmpty(query.getApplyCrowdIds())) {
            boolQueryBuilder.filter(QueryBuilders.termsQuery("applyCrowd", query.getApplyCrowdIds()));
        }
        if (query.getCostPriceMin() != null && query.getCostPriceMax() == null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("inventoryCost").gte(query.getCostPriceMin()));
        }
        if (query.getCostPriceMin() == null && query.getCostPriceMax() != null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("inventoryCost").lte(query.getCostPriceMax()));
        }
        if (query.getCostPriceMin() != null && query.getCostPriceMax() != null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("inventoryCost").from(query.getCostPriceMin()).to(query.getCostPriceMax()));
        }

        if (query.getWarehousePriceMin() != null && query.getWarehousePriceMax() == null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("warehousePrice").gte(query.getWarehousePriceMin()));
        }
        if (query.getWarehousePriceMin() == null && query.getWarehousePriceMax() != null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("warehousePrice").lte(query.getWarehousePriceMax()));
        }
        if (query.getWarehousePriceMin() != null && query.getWarehousePriceMax() != null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("warehousePrice").from(query.getWarehousePriceMin()).to(query.getWarehousePriceMax()));
        }

        if (query.getSalesPriceMin() != null && query.getSalesPriceMax() == null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("saleTaxPrice").gte(query.getSalesPriceMin()));
        }
        if (query.getSalesPriceMin() == null && query.getSalesPriceMax() != null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("saleTaxPrice").lte(query.getSalesPriceMax()));
        }
        if (query.getSalesPriceMin() != null && query.getSalesPriceMax() != null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("saleTaxPrice").from(query.getSalesPriceMin()).to(query.getSalesPriceMax()));
        }

        if (query.getSupplyPriceMin() != null && query.getSupplyPriceMax() == null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("supplyTaxPrice").gte(query.getSupplyPriceMin()));
        }
        if (query.getSupplyPriceMin() == null && query.getSupplyPriceMax() != null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("supplyTaxPrice").lte(query.getSupplyPriceMax()));
        }
        if (query.getSupplyPriceMin() != null && query.getSupplyPriceMax() != null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("supplyTaxPrice").from(query.getSupplyPriceMin()).to(query.getSupplyPriceMax()));
        }

        if (query.getPropertyColourId() != null && query.getPropertyColourId() > 0) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("materialPropData.valueId", query.getPropertyColourId()));
        }
        if (query.getPropertyMaterialId() != null && query.getPropertyMaterialId() > 0) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("materialPropData.valueId", query.getPropertyMaterialId()));
        }

        if (StringUtils.isNotEmpty(query.getPropertyBagNo())) {
            boolQueryBuilder.filter(QueryBuilders.wildcardQuery("propertyBagNo", "*" + query.getPropertyBagNo() + "*"));
        }
        if (StringUtils.isNotEmpty(query.getPropertyWatchNo())) {
            boolQueryBuilder.filter(QueryBuilders.wildcardQuery("propertyWatchNo", "*" + query.getPropertyWatchNo() + "*"));
        }

        //这里需要根据汇总数量进行查询实物数
        if (CollectionUtils.isNotEmpty(query.getWarehouseCodeList())) {
            boolQueryBuilder.filter(QueryBuilders.termsQuery("warehouseData.warehouseCode", query.getWarehouseCodeList()));
        }

        if (query.getRealStockNumMin() != null && query.getRealStockNumMax() == null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("totalRealStockNum").gte(query.getRealStockNumMin()));
        }
        if (query.getRealStockNumMin() == null && query.getRealStockNumMax() != null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("totalRealStockNum").lte(query.getRealStockNumMax()));
        }
        if (query.getRealStockNumMin() != null && query.getRealStockNumMax() != null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("totalRealStockNum").from(query.getRealStockNumMin()).to(query.getRealStockNumMax()));
        }

        if (StringUtils.isNotEmpty(query.getMaintainResult())) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("maintainResult", query.getMaintainResult()));
        }
        if (StringUtils.isNotEmpty(query.getRemarks())) {
            boolQueryBuilder.filter(QueryBuilders.wildcardQuery("remarks", "*" + query.getRemarks() + "*"));
        }

        if (query.getSalesStockNumMin() != null && query.getSalesStockNumMax() == null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("totalSalesStockNum").gte(query.getSalesStockNumMin()));
        }
        if (query.getSalesStockNumMin() == null && query.getSalesStockNumMax() != null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("totalSalesStockNum").lte(query.getSalesStockNumMax()));
        }
        if (query.getSalesStockNumMin() != null && query.getSalesStockNumMax() != null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("totalSalesStockNum").from(query.getSalesStockNumMin()).to(query.getSalesStockNumMax()));
        }
        if (query.getIsSales() != null && query.getIsSales()) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("totalSalesStockNum").gt(0));
        }
        if (query.getIsSales() != null && !query.getIsSales()) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("totalSalesStockNum", 0));
        }

        if (StringUtils.isNotEmpty(query.getVendorName())) {
            boolQueryBuilder.filter(QueryBuilders.wildcardQuery("purchaseData.vendorName", "*" + query.getVendorName() + "*"));
        }
        if (query.getPurchaseChannelId() != null && query.getPurchaseChannelId() > 0) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("purchaseData.purchaseChannelId", query.getPurchaseChannelId()));
        }
        if (query.getPurchaseTypeId() != null && query.getPurchaseTypeId() > 0) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("purchaseData.purchaseTypeId", query.getPurchaseTypeId()));
        }
        if (CollectionUtils.isNotEmpty(query.getWarehouseWayList())) {
            boolQueryBuilder.filter(QueryBuilders.termsQuery("purchaseData.warehouseWay", query.getWarehouseWayList()));
        }
        //如果没有inventoryId，那么不查询
        boolQueryBuilder.filter(QueryBuilders.existsQuery("inventoryId"));

        return boolQueryBuilder;
    }

}
